using System;
using System.Collections;
using System.Drawing;
using System.Globalization;
using PickGold.Charting;

namespace PickGold.Charting.ChartTypes
{
	internal class RenkoChart : IChartType, IDisposable
	{
		public void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list)
		{
		}

		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
		}

		private static void FillRenkoData(Series series, Series originalData)
		{
			int yValueIndex = 0;
			if (series.IsCustomPropertySet("UsedYValue"))
			{
				try
				{
					yValueIndex = int.Parse(series["UsedYValue"], CultureInfo.InvariantCulture);
				}
				catch
				{
					throw new InvalidOperationException(SR.ExceptionRenkoUsedYValueFormatInvalid);
				}
				if (yValueIndex >= series.YValuesPerPoint)
				{
					throw new InvalidOperationException(SR.ExceptionRenkoUsedYValueOutOfRange);
				}
			}
			double num2 = GetBoxSize(series, originalData, yValueIndex);
			double naN = double.NaN;
			double d = double.NaN;
			int num5 = 0;
		Label_02A5:
			foreach (DataPoint point in originalData.Points)
			{
				if (!point.IsEmpty)
				{
					int num6 = 0;
					bool flag = true;
					if (double.IsNaN(naN) || double.IsNaN(d))
					{
						d = point.YValues[yValueIndex];
						naN = point.YValues[yValueIndex];
						num5++;
						goto Label_02A5;
					}
					Color transparent = Color.Transparent;
					string text = point["PriceUpColor"];
					if (text == null)
					{
						text = series["PriceUpColor"];
					}
					if (text != null)
					{
						try
						{
							ColorConverter converter = new ColorConverter();
							transparent = (Color)converter.ConvertFromString(null, CultureInfo.InvariantCulture, text);
						}
						catch
						{
							throw new InvalidOperationException(SR.ExceptionRenkoUpBrickColorInvalid);
						}
					}
					if (point.YValues[yValueIndex] >= (d + num2))
					{
						flag = true;
						num6 = (int)Math.Floor((double)((point.YValues[yValueIndex] - d) / num2));
					}
					else if (point.YValues[yValueIndex] <= (naN - num2))
					{
						flag = false;
						num6 = (int)Math.Floor((double)((naN - point.YValues[yValueIndex]) / num2));
					}
					while (num6 > 0)
					{
						DataPoint item = point.Clone();
						item["OriginalPointIndex"] = num5.ToString(CultureInfo.InvariantCulture);
						item.series = series;
						item.YValues = new double[2];
						item.XValue = point.XValue;
						item.Tag = point;
						if (flag)
						{
							item.YValues[1] = d;
							item.YValues[0] = d + num2;
							naN = d;
							d = naN + num2;
							item.Color = transparent;
							if (item.BorderWidth < 1)
							{
								item.BorderWidth = 1;
							}
							if (item.BorderDashStyle == ChartDashStyle.NotSet)
							{
								item.BorderDashStyle = ChartDashStyle.Solid;
							}
							if (((item.BorderColor == Color.Empty) || (item.BorderColor == Color.Transparent)) && ((item.Color == Color.Empty) || (item.Color == Color.Transparent)))
							{
								item.BorderColor = series.Color;
							}
						}
						else
						{
							item.YValues[1] = naN;
							item.YValues[0] = naN - num2;
							d = naN;
							naN = d - num2;
						}
						series.Points.Add(item);
						num6--;
					}
				}
				num5++;
			}
		}

		private static double GetBoxSize(Series series, Series originalData, int yValueIndex)
		{
			double num = 1.0;
			double num2 = 4.0;
			bool flag = true;
			if (series.IsCustomPropertySet("BoxSize"))
			{
				string s = series["BoxSize"].Trim();
				bool flag2 = s.EndsWith("%", StringComparison.Ordinal);
				if (flag2)
				{
					s = s.Substring(0, s.Length - 1);
				}
				try
				{
					if (flag2)
					{
						num2 = double.Parse(s, CultureInfo.InvariantCulture);
						flag = false;
					}
					else
					{
						num = double.Parse(s, CultureInfo.InvariantCulture);
						num2 = 0.0;
					}
				}
				catch
				{
					throw new InvalidOperationException(SR.ExceptionRenkoBoxSizeFormatInvalid);
				}
			}
			if (num2 > 0.0)
			{
				num = 1.0;
				double minValue = double.MinValue;
				double maxValue = double.MaxValue;
				foreach (DataPoint point in originalData.Points)
				{
					if (!point.IsEmpty)
					{
						if (point.YValues[yValueIndex] > minValue)
						{
							minValue = point.YValues[yValueIndex];
						}
						if (point.YValues[yValueIndex] < maxValue)
						{
							maxValue = point.YValues[yValueIndex];
						}
					}
				}
				if (maxValue == minValue)
				{
					num = 1.0;
				}
				else if ((minValue - maxValue) < 1E-06)
				{
					num = 1E-06;
				}
				else
				{
					num = (minValue - maxValue) * (num2 / 100.0);
				}
				if (flag)
				{
					double[] numArray = new double[] { 
                        1E-06, 1E-05, 0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 1.0, 2.0, 2.5, 3.0, 4.0, 5.0, 7.5, 10.0, 
                        15.0, 20.0, 25.0, 50.0, 100.0, 200.0, 500.0, 1000.0, 5000.0, 10000.0, 50000.0, 100000.0, 1000000.0, 1000000.0
                     };
					for (int i = 1; i < numArray.Length; i++)
					{
						if ((num > numArray[i - 1]) && (num < numArray[i]))
						{
							num = numArray[i];
						}
					}
				}
			}
			series["CurrentBoxSize"] = num.ToString(CultureInfo.InvariantCulture);
			return num;
		}

		public virtual Image GetImage(ChartTypeRegistry registry)
		{
			return (Image)registry.ResourceManager.GetObject(this.Name + "ChartType");
		}

		public virtual LegendImageStyle GetLegendImageStyle(Series series)
		{
			return LegendImageStyle.Rectangle;
		}

		public virtual double GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex)
		{
			return point.YValues[yValueIndex];
		}

		public virtual void Paint(ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)
		{
		}

		internal static void PrepareData(Series series)
		{
			if ((string.Compare(series.ChartTypeName, "Renko", StringComparison.OrdinalIgnoreCase) == 0) && series.IsVisible())
			{
				Chart chart = series.Chart;
				if (chart == null)
				{
					throw new InvalidOperationException(SR.ExceptionRenkoNullReference);
				}
				ChartArea area = chart.ChartAreas[series.ChartArea];
				foreach (Series series2 in chart.Series)
				{
					if ((series2.IsVisible() && (series2 != series)) && (area == chart.ChartAreas[series2.ChartArea]))
					{
						throw new InvalidOperationException(SR.ExceptionRenkoCanNotCobine);
					}
				}
				Series item = new Series("RENKO_ORIGINAL_DATA_" + series.Name, series.YValuesPerPoint);
				item.Enabled = false;
				item.IsVisibleInLegend = false;
				chart.Series.Add(item);
				foreach (DataPoint point in series.Points)
				{
					item.Points.Add(point);
				}
				series.Points.Clear();
				if (series.IsCustomPropertySet("TempDesignData"))
				{
					item["TempDesignData"] = "true";
				}
				series["OldXValueIndexed"] = series.IsXValueIndexed.ToString(CultureInfo.InvariantCulture);
				series["OldYValuesPerPoint"] = series.YValuesPerPoint.ToString(CultureInfo.InvariantCulture);
				series.ChartType = SeriesChartType.RangeColumn;
				series.IsXValueIndexed = true;
				series.YValuesPerPoint = 2;
				if ((series.ChartArea.Length > 0) && series.IsXValueDateTime())
				{
					Axis axis = area.GetAxis(AxisName.X, series.XAxisType, series.XSubAxisName);
					if ((axis.Interval == 0.0) && (axis.IntervalType == DateTimeIntervalType.Auto))
					{
						bool flag = false;
						double maxValue = double.MaxValue;
						double minValue = double.MinValue;
						foreach (DataPoint point2 in item.Points)
						{
							if (!point2.IsEmpty)
							{
								if (point2.XValue != 0.0)
								{
									flag = true;
								}
								if (point2.XValue > minValue)
								{
									minValue = point2.XValue;
								}
								if (point2.XValue < maxValue)
								{
									maxValue = point2.XValue;
								}
							}
						}
						if (flag)
						{
							series["OldAutomaticXAxisInterval"] = "true";
							DateTimeIntervalType auto = DateTimeIntervalType.Auto;
							axis.interval = axis.CalcInterval(maxValue, minValue, true, out auto, series.XValueType);
							axis.intervalType = auto;
						}
					}
				}
				FillRenkoData(series, item);
			}
		}

		internal static bool UnPrepareData(Series series)
		{
			if (series.Name.StartsWith("RENKO_ORIGINAL_DATA_", StringComparison.Ordinal))
			{
				bool flag;
				int num;
				Chart chart = series.Chart;
				if (chart == null)
				{
					throw new InvalidOperationException(SR.ExceptionRenkoNullReference);
				}
				Series fromSeries = chart.Series[series.Name.Substring(20)];
				Series.MovePositionMarkers(fromSeries, series);
				fromSeries.Points.Clear();
				if (!series.IsCustomPropertySet("TempDesignData"))
				{
					foreach (DataPoint point in series.Points)
					{
						fromSeries.Points.Add(point);
					}
				}
				fromSeries.ChartType = SeriesChartType.Renko;
				bool flag2 = bool.TryParse(fromSeries["OldXValueIndexed"], out flag);
				fromSeries.IsXValueIndexed = flag2 && flag;
				if (int.TryParse(fromSeries["OldYValuesPerPoint"], NumberStyles.Any, CultureInfo.InvariantCulture, out num))
				{
					fromSeries.YValuesPerPoint = num;
				}
				fromSeries.DeleteCustomProperty("OldXValueIndexed");
				fromSeries.DeleteCustomProperty("OldYValuesPerPoint");
				series["OldAutomaticXAxisInterval"] = "true";
				if (fromSeries.IsCustomPropertySet("OldAutomaticXAxisInterval"))
				{
					fromSeries.DeleteCustomProperty("OldAutomaticXAxisInterval");
					if (fromSeries.ChartArea.Length > 0)
					{
						Axis axis = chart.ChartAreas[fromSeries.ChartArea].GetAxis(AxisName.X, fromSeries.XAxisType, fromSeries.XSubAxisName);
						axis.interval = 0.0;
						axis.intervalType = DateTimeIntervalType.Auto;
					}
				}
				chart.Series.Remove(series);
				return true;
			}
			if (series.IsCustomPropertySet("CurrentBoxSize"))
			{
				series.DeleteCustomProperty("CurrentBoxSize");
			}
			return false;
		}

		public virtual bool ApplyPaletteColorsToPoints
		{
			get
			{
				return false;
			}
		}

		public bool CircularChartArea
		{
			get
			{
				return false;
			}
		}

		public virtual bool DataPointsInLegend
		{
			get
			{
				return false;
			}
		}

		public virtual bool ExtraYValuesConnectedToYAxis
		{
			get
			{
				return true;
			}
		}

		public virtual bool HundredPercent
		{
			get
			{
				return false;
			}
		}

		public virtual bool HundredPercentSupportNegative
		{
			get
			{
				return false;
			}
		}

		public virtual string Name
		{
			get
			{
				return "Renko";
			}
		}

		public virtual bool RequireAxes
		{
			get
			{
				return true;
			}
		}

		public bool SecondYScale
		{
			get
			{
				return false;
			}
		}

		public bool SideBySideSeries
		{
			get
			{
				return false;
			}
		}

		public virtual bool Stacked
		{
			get
			{
				return false;
			}
		}

		public bool StackSign
		{
			get
			{
				return false;
			}
		}

		public virtual bool SupportLogarithmicAxes
		{
			get
			{
				return true;
			}
		}

		public virtual bool SupportStackedGroups
		{
			get
			{
				return false;
			}
		}

		public virtual bool SwitchValueAxes
		{
			get
			{
				return false;
			}
		}

		public virtual int YValuesPerPoint
		{
			get
			{
				return 1;
			}
		}

		public virtual bool ZeroCrossing
		{
			get
			{
				return false;
			}
		}
	}
}

